package com.jiangyao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.common.collect.Lists;
import com.jiangyao.manager.IntegralManager;
import com.jiangyao.common.exception.ServerException;
import com.jiangyao.common.utils.FtpClient;
import com.jiangyao.dao.IClassInfoDao;
import com.jiangyao.dao.IClassSubjectDao;
import com.jiangyao.dao.IOrgInfoDao;
import com.jiangyao.model.dto.ClassSubjectDto;
import com.jiangyao.model.dto.ClassUserDto;
import com.jiangyao.model.dto.backend.ClassSemesterDTO;
import com.jiangyao.model.dto.backend.ClassSemesterEditDTO;
import com.jiangyao.model.dto.backend.ClassSemesterSubjectDTO;
import com.jiangyao.model.dto.backend.OrgClassSemesterDTO;
import com.jiangyao.model.entity.ClassInfo;
import com.jiangyao.model.entity.ClassSemester;
import com.jiangyao.dao.IClassSemesterDao;
import com.jiangyao.model.entity.ClassSubject;
import com.jiangyao.model.entity.OrgInfo;
import com.jiangyao.model.vo.AdminUserSessionVO;
import com.jiangyao.model.vo.ClassSemesterVo;
import com.jiangyao.model.vo.ClassSubjectVo;
import com.jiangyao.model.vo.UserSubjectVo;
import com.jiangyao.model.vo.backend.ClassSemesterSubjectVO;
import com.jiangyao.model.vo.backend.ClassSemesterVO;
import com.jiangyao.model.vo.backend.OrgClassSemesterVO;
import com.jiangyao.service.ClassSemesterService;
import com.jiangyao.service.IntegralLogService;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 班级学期 服务实现类
 * </p>
 *
 * @author xiangyan
 * @since 2020-08-23
 */
@Service
public class ClassSemesterServiceImpl extends BaseServiceImpl<IClassSemesterDao, ClassSemester> implements ClassSemesterService {
    @Autowired
    private DozerBeanMapper dozerBeanMapper;

    @Autowired
    private IClassSubjectDao classSubjectDao;

    @Autowired
    private IOrgInfoDao orgInfoDao;

    @Autowired
    private IClassInfoDao classInfoDao;

    @Autowired
    private IntegralLogService integralLogService;

    @Autowired
    private IntegralManager integralManage;

    private Integer[] courseArray = {5,6,7};
    private List<Integer> courselist = Arrays.asList(courseArray);

    @Override
    public UserSubjectVo getUserClassSubject(ClassUserDto dto) {
        UserSubjectVo vo = new UserSubjectVo();
        vo.setIntegral(integralLogService.getIntegralSumByTypeList(courselist));
        QueryWrapper<ClassSemester> params = new QueryWrapper();
        params.eq("org_id", dto.getOrgId()).eq("class_id", dto.getClassId()).eq("status", 1);
        List<ClassSemester> list = this.list(params);
        List<ClassSemesterVo> classSubjectList = new ArrayList<>();
        for (ClassSemester semester : list) {
            ClassSemesterVo info = dozerBeanMapper.map(semester, ClassSemesterVo.class);

            ClassSubjectDto semesterParams = new ClassSubjectDto(semester.getOrgId(), semester.getClassId(), semester.getSemesterId(), 1);
            List<ClassSubjectVo> semesterSubject=classSubjectDao.getClassSubjectList(semesterParams);
            info.setSemesterSubject(semesterSubject);

            ClassSubjectDto onlineParams = new ClassSubjectDto(semester.getOrgId(), semester.getClassId(), semester.getSemesterId(), 2);
            List<ClassSubjectVo> onlineSubject=classSubjectDao.getClassSubjectList(onlineParams);
            if (!CollectionUtils.isEmpty(onlineSubject)) {
                for(ClassSubjectVo obj:onlineSubject){
                    obj.setSubjectCover(FtpClient.fullFtpUrl(obj.getSubjectCover()));
                    ClassSubjectDto processParams = new ClassSubjectDto(semester.getOrgId(), semester.getClassId(), semester.getSemesterId(),obj.getSubjectId(),getLoginApiUserId());
                    BigDecimal progressPercent = classSubjectDao.getClassSubjectPercent(processParams);
                    if (progressPercent == null) {
                        progressPercent = BigDecimal.ZERO;
                    }
                    if (progressPercent.compareTo(BigDecimal.valueOf(100)) > 0) {
                        progressPercent = BigDecimal.valueOf(100);
                    }
                    obj.setProgressPercent(progressPercent);
                }
            }
            info.setOnlineSubject(onlineSubject);
            classSubjectList.add(info);
        }
        vo.setClassSubjectList(classSubjectList);
        return vo;
    }

    @Override
    public OrgClassSemesterVO getOrgClassSemesterList(ClassSemesterEditDTO editDTO) {
        ClassInfo classInfo = classInfoDao.selectById(editDTO.getClassId());
        if (classInfo == null) {
            throw new ServerException(100, "班级不存在");
        }
        OrgInfo orgInfo = orgInfoDao.selectById(classInfo.getOrgId());
        if (orgInfo == null) {
            throw new ServerException(100, "班级所在组织不存在");
        }
        // 检查组织班级权限
        checkAuthority(classInfo.getOrgId(),classInfo.getClassId());

        OrgClassSemesterVO result = new OrgClassSemesterVO();
        result.setClassId(classInfo.getClassId());
        result.setClassName(classInfo.getClassName());
        result.setOrgId(orgInfo.getOrgId());
        result.setOrgName(orgInfo.getOrgName());
        result.setOrgType(orgInfo.getOrgType());

        // 获取学期列表
        QueryWrapper<ClassSemester> classSemesterQW = new QueryWrapper<>();
        classSemesterQW.eq("class_id", classInfo.getClassId());
        classSemesterQW.eq("org_id", classInfo.getOrgId());
        classSemesterQW.eq("status", 1);
        classSemesterQW.select("semester_id", "semester_type", "semester_name", "sort_order");
        classSemesterQW.orderByAsc("sort_order");
        List<ClassSemester> classSemesterList = this.list(classSemesterQW);
        if (CollectionUtils.isEmpty(classSemesterList)) {
            return result;
        }
        // 学期ID集合
        List<Integer> semesterIdList = Lists.newArrayListWithCapacity(classSemesterList.size());
        // 学期VO集合
        List<ClassSemesterVO> semesterList = Lists.newArrayListWithCapacity(classSemesterList.size());

        classSemesterList.forEach(cs -> {
            semesterIdList.add(cs.getSemesterId());
            ClassSemesterVO vo = ClassSemesterVO.builder()
                    .semesterId(cs.getSemesterId()).semesterName(cs.getSemesterName()).semesterType(cs.getSemesterType())
                    .sortOrder(cs.getSortOrder()).classroomSubjectList(new ArrayList<>()).onlineSubjectList(new ArrayList<>())
                    .build();
            semesterList.add(vo);
        });
        result.setSemesterList(semesterList);

        // 获取学期课程
        List<ClassSemesterSubjectVO> semesterSubjectList = classSubjectDao.getListBySemesterIdList(semesterIdList);
        if (CollectionUtils.isEmpty(semesterSubjectList)) {
            return result;
        }
        semesterList.forEach(vo -> {
            semesterSubjectList.forEach(ss -> {
                if (vo.getSemesterId().equals(ss.getSemesterId())) {
                    if (ss.getType() != null && ss.getType() == 1) {
                        vo.getClassroomSubjectList().add(ss);
                    } else {
                        vo.getOnlineSubjectList().add(ss);
                    }

                }
            });
        });
        return result;
    }

    /**
     * 检查组织班级权限
     *
     * @param orgId   组织ID
     * @param classId 班级ID
     */
    private void checkAuthority(Integer orgId, Integer classId) {
        AdminUserSessionVO sessionVO = getAdminLoginSession();
        if (!CollectionUtils.isEmpty(sessionVO.getOrgIdList()) && !sessionVO.getOrgIdList().contains(orgId)) {
            throw new ServerException(100, "该组织班级下无操作权限");
        }
        if (!CollectionUtils.isEmpty(sessionVO.getClassIdList()) && !sessionVO.getClassIdList().contains(classId)) {
            throw new ServerException(100, "该组织班级下无操作权限");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateOrgClassSemesterList(OrgClassSemesterDTO orgClassSemesterDTO) {
        ClassInfo classInfo = classInfoDao.selectById(orgClassSemesterDTO.getClassId());
        if (classInfo == null) {
            throw new ServerException(100, "班级不存在");
        }
        OrgInfo orgInfo = orgInfoDao.selectById(classInfo.getOrgId());
        if (orgInfo == null) {
            throw new ServerException(100, "班级所在组织不存在");
        }
        // 检查组织班级权限
        checkAuthority(classInfo.getOrgId(),classInfo.getClassId());

        if (CollectionUtils.isEmpty(orgClassSemesterDTO.getSemesterList())) {
            return;
        }
        // 编辑班级学期
        orgClassSemesterDTO.getSemesterList().forEach(dto -> updateClassSemester(classInfo, dto));

    }

    /**
     * 编辑班级学期
     *
     * @param classInfo   班级信息
     * @param semesterDTO 班级学期
     */
    private void updateClassSemester(ClassInfo classInfo, ClassSemesterDTO semesterDTO) {
        Integer semesterId = semesterDTO.getSemesterId();
        // 新增学期
        if (semesterId == null || semesterId == 0) {
            ClassSemester classSemester = dozerBeanMapper.map(semesterDTO, ClassSemester.class);
            classSemester.setOrgId(classInfo.getOrgId());
            classSemester.setClassId(classInfo.getClassId());
            classSemester.setSemesterId(null);
            classSemester.setStatus(1);
            classSemester.setCreateTime(new Date());
            classSemester.setCreateAdminId(getLoginAdminUserId());
            this.save(classSemester);
            semesterId = classSemester.getSemesterId();
        } else {
            // 编辑学期
            UpdateWrapper<ClassSemester> uw = new UpdateWrapper<>();
            uw.eq("semester_id", semesterId);
            uw.eq("org_id", classInfo.getOrgId());
            uw.eq("class_id", classInfo.getClassId());
            uw.set("semester_type", semesterDTO.getSemesterType());
            uw.set("semester_name", semesterDTO.getSemesterName());
            uw.set("sort_order", semesterDTO.getSortOrder());
            this.update(uw);
        }
        // 编辑班级课程
        // 课程教学
        if (!CollectionUtils.isEmpty(semesterDTO.getClassroomSubjectList())) {
            Integer finalSemesterId = semesterId;
            // 班级课程ID集合
            List<Integer> clsubIdList = Lists.newArrayListWithCapacity(semesterDTO.getClassroomSubjectList().size());
            semesterDTO.getClassroomSubjectList().forEach(dto -> {
                Integer clsubId = updateClassSubject(classInfo, finalSemesterId, dto);
                clsubIdList.add(clsubId);
            });
            // 保存积分流水日志-课堂教学完成时
            integralManage.saveIntegralLogForClassroomSubject(clsubIdList);
        }

        // 在线课程
        if (!CollectionUtils.isEmpty(semesterDTO.getOnlineSubjectList())) {
            Integer finalSemesterId = semesterId;
            semesterDTO.getOnlineSubjectList().forEach(dto -> updateClassSubject(classInfo, finalSemesterId, dto));
        }

    }

    /**
     * 编辑班级课程
     *
     * @param classInfo  班级信息
     * @param semesterId 班级学期ID
     * @param subjectDTO 课程DTO
     */
    private Integer updateClassSubject(ClassInfo classInfo, Integer semesterId, ClassSemesterSubjectDTO subjectDTO) {
        Integer clsubId = subjectDTO.getClsubId();
        // 新增学期课程
        if (clsubId == null || clsubId == 0) {
            ClassSubject classSubject = dozerBeanMapper.map(subjectDTO, ClassSubject.class);
            classSubject.setOrgId(classInfo.getOrgId());
            classSubject.setClassId(classInfo.getClassId());
            classSubject.setSemesterId(semesterId);
            classSubject.setClsubId(null);
            classSubject.setStatus(1);
            classSubject.setCreateTime(new Date());
            classSubject.setCreateAdminId(getLoginAdminUserId());
            classSubjectDao.insert(classSubject);
            clsubId = classSubject.getClsubId();
        } else {
            // 编辑学期
            UpdateWrapper<ClassSubject> uw = new UpdateWrapper<>();
            uw.eq("clsub_id", clsubId);
            uw.eq("semester_id", semesterId);
            uw.eq("org_id", classInfo.getOrgId());
            uw.eq("class_id", classInfo.getClassId());
            uw.set("subject_id", subjectDTO.getSubjectId());
            uw.set("subject_name", subjectDTO.getSubjectName());
            uw.set("learn_status", subjectDTO.getLearnStatus());
            uw.set("sort_order", subjectDTO.getSortOrder());
            classSubjectDao.update(null, uw);
        }
        return clsubId;
    }

    @Override
    public void deleteClassSemester(ClassSemesterEditDTO editDTO) {
        ClassInfo classInfo = classInfoDao.selectById(editDTO.getClassId());
        if (classInfo == null) {
            throw new ServerException(100, "班级不存在");
        }
        OrgInfo orgInfo = orgInfoDao.selectById(classInfo.getOrgId());
        if (orgInfo == null) {
            throw new ServerException(100, "班级所在组织不存在");
        }
        // 检查组织班级权限
        checkAuthority(classInfo.getOrgId(),classInfo.getClassId());
        if (editDTO.getSemesterId() != null && editDTO.getSemesterId() != 0) {
            UpdateWrapper<ClassSemester> uw = new UpdateWrapper<>();
            uw.eq("semester_id", editDTO.getSemesterId());
            uw.set("status", 0);
            this.update(uw);
        }

        if (editDTO.getClsubId() != null && editDTO.getClsubId() != 0) {
            UpdateWrapper<ClassSubject> uw = new UpdateWrapper<>();
            uw.eq("clsub_id", editDTO.getClsubId());
            uw.set("status", 0);
            classSubjectDao.update(null, uw);
        }
    }
}
